/* 业务处理超时，查看服务器的处理情况
    当服务器达到了一个性能瓶颈，在一次业务处理中花费了太长的时间（超过了服务器设置的非活跃超时时间）
     1. 在一次业务处理中耗费太长时间，导致其他的连接也被连累超时，其他的连接有可能会被拖累超时释放
     假设现在  12345描述符就绪了， 在处理1的时候花费了30s处理完，超时了，导致2345描述符因为长时间没有刷新活跃度
       1. 如果接下来的2345描述符都是通信连接描述符，如果都就绪了，则并不影响，因为接下来就会进行处理并刷新活跃度
       2. 如果接下来的2号描述符是定时器事件描述符，定时器触发超时，执行定时任务，就会将345描述符给释放掉
          这时候一旦345描述符对应的连接被释放，接下来在处理345事件的时候就会导致程序崩溃（内存访问错误）
          因此这时候，在本次事件处理中，并不能直接对连接进行释放，而应该将释放操作压入到任务池中，
          等到事件处理完了执行任务池中的任务的时候，再去释放
*/

#include "../source/server.hpp"

int main()
{
    signal(SIGCHLD, SIG_IGN);
    for (int i = 0; i < 10; i++) {
        pid_t pid = fork();
        if (pid < 0) {
            DBG_LOG("FORK ERROR");
            return -1;
        }else if (pid == 0) {
            Socket cli_sock;
            cli_sock.CreatClient(9999, "127.0.0.1");
            std::string req = "GET /hello HTTP/1.1\r\nConnection: keep-alive\r\nContent-Length: 0\r\n\r\n";
            while(1) {
                assert(cli_sock.Send(req.c_str(), req.size()) != -1);
                char buf[1024] = {0};
                assert(cli_sock.Recv(buf, 1023));
                DBG_LOG("[%s]", buf);
            }
            cli_sock.Close();
            exit(0);
        }
    }
    while(1) sleep(1);
    
    return 0;
}


// 这段内容是在讲解服务器业务处理超时场景下的连接管理风险，以及如何通过 “任务池延迟释放” 来避免程序崩溃，核心逻辑如下：
// 1. 场景：业务处理超时，拖累其他连接
// 假设服务器有多个连接（比如描述符 1、2、3、4、5），当连接 1 的业务处理耗时过长（超过了服务器设置的 “非活跃超时时间”），会引发连锁反应：
// 连接 1 的处理阻塞了事件循环，导致其他连接（2、3、4、5）的活跃度无法及时刷新。
// 若这些连接的 “非活跃超时时间” 到期，服务器会触发超时释放逻辑，试图关闭它们。
// 2. 风险：内存访问错误（程序崩溃）
// 如果在 “处理连接 1 的业务” 过程中，直接释放了连接 3、4、5，会出现严重问题：
// 连接 3、4、5 被释放后，其内存资源（如Connection对象）已被回收。
// 但事件循环后续仍可能触发这些连接的事件（比如它们的描述符之前已被 epoll 监控），此时访问已回收的内存，会导致内存访问错误（段错误），程序崩溃。
// 3. 解决方案：任务池延迟释放
// 为了避免这种风险，需要将 “连接释放” 操作 “延迟” 到当前业务处理完成后执行，具体做法是：
// 当检测到连接超时需要释放时，不立即执行释放逻辑，而是将 “释放操作”压入一个 “任务池”。
// 等当前业务处理完毕、事件循环执行到 “任务池任务” 阶段时，再从任务池中取出并执行释放操作。
// 这样可以确保：在释放连接前，所有对该连接的事件处理已完成，不会出现 “释放后还访问其内存” 的情况，从而避免程序崩溃。
// 简单来说，这是一种 **“延迟执行” 的编程技巧 **，通过 “任务池” 将 “高风险操作（释放连接）” 与 “当前业务处理” 解耦，保证内存访问的安全性。


// 这个其实就是为了某些场景被释放做出的保护操作，不是提升性能而是压入任务池，任务实在处理完这个描述符所有事件在执行，所以释放放到最晚


//并且改动，定时器应该根据实际的超时次数去执行超时任务， // 有可能因为其他描述符的事件处理花费事件比较长，然后在处理定时器描述符事件的时候，有可能就已经超时了很多次read读取到的数据times就是从上一次read之后超时的次数
//释放不应该直接释放，压入任务池释放
//事件处理中不会释放，可以把活跃度唤醒放后面,eventcallback